#include "lvgl/lvgl.h"
#include "lvgl/demos/lv_demos.h"
#include "lv_drivers/display/fbdev.h"
#include "lv_drivers/indev/evdev.h"
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <sys/time.h>
#include "lv_chinese_ime/lv_chinese_ime.h"
#include "lv_chinese_ime/src/chinese_ime.h"
//#include "lv_lib_tinygl/lv_tinygl_test.h"

#define DISP_BUF_SIZE (128 * 1024)

lv_obj_t *obj ;
lv_obj_t *cb[5];
lv_obj_t *label ;
lv_obj_t *title ;
#define _UxGT(a) a
#define SCREEN_WIDTH    480
#define SCREEN_HEIGHT   800
#define NR(x) sizeof(x)/sizeof(x[0])

enum
{
    CHINESE=0,
    ENGLISH,
    JAPANESE,
    FRENCH,
    GERMAN
};

const wchar_t *lang_str[] =
{
    _UxGT("你好中国"),
    _UxGT("English"),
    _UxGT("こんにちは"),
    _UxGT("Bonjour la Chine"),
    _UxGT("Hallo China"),
};

static void switch_event_cb2(lv_event_t * e)
{
    int8_t cb_index = -1;
    lv_obj_t *cb_obj = lv_event_get_target(e);
    lv_event_code_t code = lv_event_get_code(e);
    if(LV_EVENT_VALUE_CHANGED == code)
    {
        for(uint8_t i = 0 ; i < NR(cb) ; i++)
        {
            if(cb_obj == cb[i])
                cb_index = i ;
        }
        switch(cb_index)
        {
        case 0:
            lv_obj_add_state(cb[0],LV_STATE_CHECKED);
            lv_obj_clear_state(cb[1], LV_STATE_CHECKED);
            lv_obj_clear_state(cb[2], LV_STATE_CHECKED);
            lv_obj_clear_state(cb[3], LV_STATE_CHECKED);
            lv_obj_clear_state(cb[4], LV_STATE_CHECKED);
            break ;
        case 1:
            lv_obj_add_state(cb[1],LV_STATE_CHECKED);
            lv_obj_clear_state(cb[0], LV_STATE_CHECKED);
            lv_obj_clear_state(cb[2], LV_STATE_CHECKED);
            lv_obj_clear_state(cb[3], LV_STATE_CHECKED);
            lv_obj_clear_state(cb[4], LV_STATE_CHECKED);
            break ;
        case 2:
            lv_obj_add_state(cb[2],LV_STATE_CHECKED);
            lv_obj_clear_state(cb[0], LV_STATE_CHECKED);
            lv_obj_clear_state(cb[1], LV_STATE_CHECKED);
            lv_obj_clear_state(cb[3], LV_STATE_CHECKED);
            lv_obj_clear_state(cb[4], LV_STATE_CHECKED);
            break ;
        case 3:
            lv_obj_add_state(cb[3],LV_STATE_CHECKED);
            lv_obj_clear_state(cb[0], LV_STATE_CHECKED);
            lv_obj_clear_state(cb[1], LV_STATE_CHECKED);
            lv_obj_clear_state(cb[2], LV_STATE_CHECKED);
            lv_obj_clear_state(cb[4], LV_STATE_CHECKED);
            break ;

        case 4:
            lv_obj_add_state(cb[4],LV_STATE_CHECKED);
            lv_obj_clear_state(cb[0], LV_STATE_CHECKED);
            lv_obj_clear_state(cb[1], LV_STATE_CHECKED);
            lv_obj_clear_state(cb[2], LV_STATE_CHECKED);
            lv_obj_clear_state(cb[3], LV_STATE_CHECKED);
            break ;
        default:
            break;
        }
        lv_label_set_text(label,lang_str[cb_index]);
    }
}

LV_FONT_DECLARE(siyuan_black);
static lv_style_t label_style ;
void lvgl_test_demo_study()
{
    lv_style_init(&label_style);
    lv_style_set_bg_opa(&label_style,LV_OPA_COVER);
    lv_style_set_bg_color(&label_style,lv_color_hex(0xffffff));

    title = lv_label_create(lv_scr_act());
    lv_obj_add_style(title,&label_style,0);
    lv_obj_set_pos(title,0,0);
    lv_label_set_text(title,_UxGT("Language Setting"));

    label = lv_label_create(obj);
    lv_obj_align(label,LV_ALIGN_CENTER, 0, -50);
    lv_obj_add_style(label,&label_style,0);
    lv_obj_set_style_text_font(label, &siyuan_black, 0);
    lv_label_set_text(label,lang_str[0]);

    cb[0] = lv_checkbox_create(obj);
    lv_checkbox_set_text(cb[0], "Chinese");
    lv_obj_align_to(cb[0],label,LV_ALIGN_LEFT_MID,-40,40);
    lv_obj_set_style_bg_color(cb[0], lv_color_hex(0xE3EAF4), LV_STATE_DEFAULT);


    cb[1] = lv_checkbox_create(obj);
    lv_checkbox_set_text(cb[1], "English");
    lv_obj_align_to(cb[1],cb[0],LV_ALIGN_LEFT_MID,100,0);
    lv_obj_set_style_bg_color(cb[1], lv_color_hex(0xE3EAF4), LV_STATE_DEFAULT);

    cb[2] = lv_checkbox_create(obj);
    lv_checkbox_set_text(cb[2], "Japanese");
    lv_obj_align_to(cb[2],cb[0],LV_ALIGN_LEFT_MID,0,30);
    lv_obj_set_style_bg_color(cb[2], lv_color_hex(0xE3EAF4), LV_STATE_DEFAULT);

    cb[3] = lv_checkbox_create(obj);
    lv_checkbox_set_text(cb[3], "French");
    lv_obj_align_to(cb[3],cb[2],LV_ALIGN_LEFT_MID,100,0);
    lv_obj_set_style_bg_color(cb[3], lv_color_hex(0xE3EAF4), LV_STATE_DEFAULT);

    cb[4] = lv_checkbox_create(obj);
    lv_checkbox_set_text(cb[4], "German");
    lv_obj_align_to(cb[4],cb[2],LV_ALIGN_LEFT_MID,0,30);
    lv_obj_set_style_bg_color(cb[4], lv_color_hex(0xE3EAF4), LV_STATE_DEFAULT);

    for(uint8_t i = 0 ; i < NR(cb) ; i++)
        lv_obj_add_event_cb(cb[i],switch_event_cb2,LV_EVENT_VALUE_CHANGED,NULL);

    lv_obj_add_state(cb[0],LV_STATE_CHECKED);
}
int main(void)
{
    /*LittlevGL init*/
    lv_init();

    /*Linux frame buffer device init*/
    fbdev_init();

    /*A small buffer for LittlevGL to draw the screen's content*/
    static lv_color_t buf[DISP_BUF_SIZE];

    /*Initialize a descriptor for the buffer*/
    static lv_disp_draw_buf_t disp_buf;
    lv_disp_draw_buf_init(&disp_buf, buf, NULL, DISP_BUF_SIZE);

    /*Initialize and register a display driver*/
    static lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    disp_drv.draw_buf   = &disp_buf;
    disp_drv.flush_cb   = fbdev_flush;
    disp_drv.hor_res    = SCREEN_WIDTH;
    disp_drv.ver_res    = SCREEN_HEIGHT;
    lv_disp_drv_register(&disp_drv);

    evdev_init();
    static lv_indev_drv_t indev_drv_1;
    lv_indev_drv_init(&indev_drv_1); /*Basic initialization*/
    indev_drv_1.type = LV_INDEV_TYPE_POINTER;

    /*This function will be called periodically (by the library) to get the mouse position and state*/
    indev_drv_1.read_cb = evdev_read;
    lv_indev_t *mouse_indev = lv_indev_drv_register(&indev_drv_1);


    /*Set a cursor for the mouse*/
    LV_IMG_DECLARE(mouse_cursor_icon)
    lv_obj_t * cursor_obj = lv_img_create(lv_scr_act()); /*Create an image object for the cursor */
    lv_img_set_src(cursor_obj, &mouse_cursor_icon);           /*Set the image source*/
    lv_indev_set_cursor(mouse_indev, cursor_obj);             /*Connect the image  object to the driver*/

    obj = lv_obj_create(lv_scr_act());
    lv_obj_set_size(obj,SCREEN_WIDTH,SCREEN_HEIGHT);
    lv_obj_center(obj);
    lv_obj_set_style_bg_color(obj,  lv_color_hex(0xE3EAF4), LV_STATE_DEFAULT);
    lvgl_test_demo_study();

    /*Handle LitlevGL tasks (tickless mode)*/
    while(1) {
        lv_timer_handler();
        usleep(5000);
    }

    return 0;
}

/*Set in lv_conf.h as `LV_TICK_CUSTOM_SYS_TIME_EXPR`*/
uint32_t custom_tick_get(void)
{
    static uint64_t start_ms = 0;
    if(start_ms == 0) {
        struct timeval tv_start;
        gettimeofday(&tv_start, NULL);
        start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;
    }

    struct timeval tv_now;
    gettimeofday(&tv_now, NULL);
    uint64_t now_ms;
    now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;

    uint32_t time_ms = now_ms - start_ms;
    return time_ms;
}
